class Game {
  constructor() {
    this.time = 60;
    this.totalNum = 0;
    this.level = 2000;
    this.timeOut = null;
    this.isPlaying = false;
    this.isPaused = false;
    this.mouseTimeouts = [];
    this.play = this.play.bind(this);
    this.loadHighScore();
  }

  getById(id) {
    return document.getElementById(id);
  }

  play() {
    if (this.isPlaying && !this.isPaused) return;
    
    if (this.isPaused) {
      this.isPaused = false;
      return;
    }
    
    this.isPlaying = true;
    this.time = 60;
    this.totalNum = 0;
    this.getById("time").innerText = this.time;
    this.getById("hitNum").innerText = this.totalNum;

    this.timeOut = setInterval(() => {
      if (!this.isPaused) {
        this.time--;
        if (this.time === 0) {
          this.end();
        }
        this.getById("time").innerText = this.time;
        this.getRadom();
      }
    }, 1000);
  }

  getRadom() {
    if (this.isPaused) return;
    
    let nums = this.getById("mouseFrame").children.length;
    let randomNum = parseInt(Math.random() * nums);
    let curMouse = this.getById("mouseFrame").children[randomNum];
    curMouse.className = "mouse out";

    if (this.totalNum % 5 === 0 && this.totalNum > 0) {
      this.level = Math.max(100, this.level - 100);
    }

    const timeoutId = setTimeout(() => {
      if (!this.isPaused) {
        curMouse.className = "mouse";
      }
    }, this.level);
    
    this.mouseTimeouts.push(timeoutId);
  }

  end() {
    clearInterval(this.timeOut);
    this.mouseTimeouts.forEach(timeout => clearTimeout(timeout));
    this.mouseTimeouts = [];
    
    const mice = this.getById("mouseFrame").children;
    for (let i = 0; i < mice.length; i++) {
      mice[i].className = "mouse";
    }
    
    this.isPlaying = false;
    this.isPaused = false;
    this.getById("time").innerText = 60;
    this.getById("hitNum").innerText = 0;
    this.getById("level").value = 2000;
    this.level = 2000;

    const endSound = this.getById("endSound");
    endSound.play();

    this.updateHighScore();
    this.createFireworks();
  }

  createFireworks() {
    const colors = [
      '#ff0000', '#00ff00', '#0000ff', '#ffff00', 
      '#ff00ff', '#00ffff', '#ff8800', '#ff0088'
    ];
    const gameBox = this.getById("gameBox");
    const boxRect = gameBox.getBoundingClientRect();
    
    // 创建8个烟花爆炸中心点
    for (let i = 0; i < 8; i++) {
      setTimeout(() => {
        this.createFirework(
          gameBox,
          Math.random() * boxRect.width,
          Math.random() * boxRect.height * 0.5,
          colors
        );
      }, i * 300);
    }
    
    // 创建500个彩花粒子
    for (let i = 0; i < 500; i++) {
      setTimeout(() => {
        this.createParticle(gameBox, colors, boxRect);
      }, Math.random() * 2000);
    }
  }

  createFirework(container, x, y, colors) {
    const firework = document.createElement('div');
    firework.className = 'firework';
    firework.style.left = x + 'px';
    firework.style.top = y + 'px';
    
    // 随机选择3种颜色
    const color1 = this.getRandomColor(colors);
    const color2 = this.getRandomColor(colors);
    const color3 = this.getRandomColor(colors);
    
    // 设置CSS变量
    firework.style.setProperty('--color1', color1.rgb);
    firework.style.setProperty('--color2', color2.rgb);
    firework.style.setProperty('--color3', color3.rgb);
    
    // 随机设置爆炸方向和扩散范围
    const angle1 = Math.random() * Math.PI * 2;
    const angle2 = Math.random() * Math.PI * 2;
    const angle3 = Math.random() * Math.PI * 2;
    
    const distance1 = 30 + Math.random() * 70;
    const distance2 = 30 + Math.random() * 70;
    const distance3 = 30 + Math.random() * 70;
    
    firework.style.setProperty('--dx1', Math.cos(angle1) * distance1 + 'px');
    firework.style.setProperty('--dy1', Math.sin(angle1) * distance1 + 'px');
    firework.style.setProperty('--spread1', Math.random() * 10 + 5 + 'px');
    
    firework.style.setProperty('--dx2', Math.cos(angle2) * distance2 + 'px');
    firework.style.setProperty('--dy2', Math.sin(angle2) * distance2 + 'px');
    firework.style.setProperty('--spread2', Math.random() * 10 + 5 + 'px');
    
    firework.style.setProperty('--dx3', Math.cos(angle3) * distance3 + 'px');
    firework.style.setProperty('--dy3', Math.sin(angle3) * distance3 + 'px');
    firework.style.setProperty('--spread3', Math.random() * 10 + 5 + 'px');
    
    container.appendChild(firework);
    
    setTimeout(() => {
      firework.remove();
    }, 1500);
  }

  createParticle(container, colors, boxRect) {
    const confetti = document.createElement('div');
    const types = ['circle', 'square', 'star'];
    const type = types[Math.floor(Math.random() * types.length)];
    
    confetti.className = `confetti ${type}`;
    
    // 随机位置 - 从顶部区域开始
    const startX = Math.random() * boxRect.width;
    const startY = -10 - Math.random() * 50;
    
    // 随机结束位置偏移
    const endX = (Math.random() - 0.5) * boxRect.width * 0.8;
    const endY = boxRect.height + 10;
    
    // 随机旋转
    const rotation = Math.random() * 720 - 360;
    
    // 随机颜色
    const color = this.getRandomColor(colors);
    confetti.style.color = color.hex;
    confetti.style.backgroundColor = type !== 'star' ? color.hex : 'transparent';
    
    // 设置CSS变量
    confetti.style.setProperty('--tx', endX + 'px');
    confetti.style.setProperty('--ty', endY + 'px');
    confetti.style.setProperty('--rot', rotation + 'deg');
    
    // 随机大小
    const size = Math.random() * 6 + 4;
    confetti.style.width = size + 'px';
    confetti.style.height = size + 'px';
    
    // 随机延迟
    const delay = Math.random() * 1.5;
    confetti.style.animationDelay = delay + 's';
    
    // 随机持续时间
    const duration = 1.5 + Math.random() * 2;
    confetti.style.animationDuration = duration + 's';
    
    confetti.style.left = startX + 'px';
    confetti.style.top = startY + 'px';
    
    container.appendChild(confetti);
    
    setTimeout(() => {
      confetti.remove();
    }, (duration + delay) * 1000);
  }

  getRandomColor(colors) {
    const hex = colors[Math.floor(Math.random() * colors.length)];
    const r = parseInt(hex.substr(1, 2), 16);
    const g = parseInt(hex.substr(3, 2), 16);
    const b = parseInt(hex.substr(5, 2), 16);
    return {
      hex: hex,
      rgb: `${r}, ${g}, ${b}`
    };
  }

  pause() {
    if (!this.isPlaying || this.isPaused) return;
    
    this.isPaused = true;
    const mice = this.getById("mouseFrame").children;
    for (let i = 0; i < mice.length; i++) {
      if (mice[i].className.includes("out")) {
        mice[i].className = "mouse";
      }
    }
  }

  hitMouse() {
    const mouseFrame = this.getById("mouseFrame");

    mouseFrame.addEventListener("mousedown", () => {
      const gameBox = this.getById("gameBox");
      gameBox.className = gameBox.className === "mouses-box"
        ? "mouses-box mouses-box-down"
        : "mouses-box";
    });

    mouseFrame.addEventListener("mouseup", () => {
      const gameBox = this.getById("gameBox");
      gameBox.className = "mouses-box";
    });

    mouseFrame.addEventListener("click", (e) => {
      if (this.isPaused) return;
      
      let target = e.target;
      let className = target.className;
      if (className.indexOf("out") !== -1) {
        target.className = "mouse";
        this.getById("hitNum").innerText = ++this.totalNum;

        const hitSound = this.getById("hitSound");
        hitSound.currentTime = 0;
        hitSound.play();
      }
    });
  }

  changeLevel(val) {
    this.level = val - 0;
  }

  gameOver() {
    this.end();
  }

  loadHighScore() {
    const highScore = localStorage.getItem('whacAMoleHighScore') || 0;
    this.getById("highScoreValue").innerText = highScore;
  }

  updateHighScore() {
    const currentScore = this.totalNum;
    const highScore = localStorage.getItem('whacAMoleHighScore') || 0;
    if (currentScore > highScore) {
      localStorage.setItem('whacAMoleHighScore', currentScore);
      this.getById("highScoreValue").innerText = currentScore;
    }
  }
}

let game = new Game();
game.hitMouse();

function handleStartClick() {
  playButtonSound();
  animateButton(event.target);
  setTimeout(() => {
    game.play();
  }, 200);
}

function handleGameOverClick() {
  playButtonSound();
  animateButton(event.target);
  setTimeout(() => {
    game.gameOver();
  }, 200);
}

function handlePauseClick() {
  playButtonSound();
  animateButton(event.target);
  setTimeout(() => {
    game.pause();
  }, 200);
}

function selectChange(val) {
  game.changeLevel(val);
}

function animateButton(button) {
  button.classList.add('active');
  setTimeout(() => {
    button.classList.remove('active');
  }, 200);
}

function playButtonSound() {
  const buttonSound = document.getElementById('buttonSound');
  if (buttonSound) {
    buttonSound.currentTime = 0;
    buttonSound.play();
  }
}